$().ready(function() {
	checkVer()
	FastClick.attach(document.body)
	window.onbeforeunload=function() {
		if (_conn) {
			_conn.close()
		}
	}
	lscache.flushExpired()

	var happiness = getUrlParam("happiness")
	if (happiness) {
		$("#scene").css({"background-color":"#f2f5f1"})
		$("#footer").css({"color":"#666"})
	} else {
		$("#scene").css({"background-color":"#00A8DB"})
	}

	var _sketch = $("#sketch")
	var _can = $("#can")
	var _backCan = $("#backCan")
	var _userWorkCan = $('<canvas></canvas>')
	var _ctx = _can[0].getContext("2d")
	var _backCtx = _backCan[0].getContext("2d")
	var _userWorkCtx = _userWorkCan[0].getContext("2d")
	var _canX = _can.offset().left
	var _canY = _can.offset().top
	var _lastX
	var _lastY
	var _touching = false
	var _offsetY = 0
	if (isTouchDevice()){
		_offsetY = 0
	}
	var _toolShow = false
	// var _replay = []
	var _currStroke = []
	var _undoStrokes = []
	var _redoStrokes = []
	var _undoLimit = 5
	var _currColor = null
	var _currLineWidth = null
	var _toolLabelColor = "#888"
	var _toolLabelDisableColor = "#ddd"
	var _undoLabel = $("#undo>.toolLabel")
	var _redoLabel = $("#redo>.toolLabel")
	var _brushTip = $("#brushTip")
	var _paintEnable = false
	var _toolBar = $("#toolbar")
	var _userBar = $("#userBar")
	var _talkBar = $("#talkBar")
	var _endRoundPanel = $("#endRoundPanelCont")
	var _endRoundText = $("#endRoundText")
	var _endGameLayer = $("#endGameLayer")
	var _endGamePanel = $("#endGamePanel")

	var DRAWST_ENTER = "enter"
	var DRAWST_START = "start"
	var DRAWST_ROUND = "round"
	var DRAWST_ROUND_END = "roundEnd"
	var DRAWST_END   = "end"

	var w = _can.width()
	var h = _can.height()
	_can[0].width = w
	_can[0].height = h
	_backCan[0].width = w
	_backCan[0].height = h
	_backCtx.fillStyle="#ffffff";
	_backCtx.fillRect(0,0,w,h);
	_userWorkCan[0].width = w
	_userWorkCan[0].height = h
	_userWorkCan.css({width:"100%",height:h+"px"})
	_ctx.lineJoin = "round"
	_ctx.lineCap = "round"
	_backCtx.lineJoin = "round"
	_backCtx.lineCap = "round"
	_undoLabel.css("color", _toolLabelDisableColor)
	_redoLabel.css("color", _toolLabelDisableColor)

	//
	var _ptOffset = 0.5
	_sketch[0].ontouchstart = function(event){
		if (!_paintEnable) {
			return
		}
		event.preventDefault()

		var touch = event.touches[0]
		var x = touch.pageX-_canX+_ptOffset
		var y = touch.pageY-_canY+_ptOffset
		onTouchStart(x, y)
	}

	_sketch[0].ontouchmove = function(event){
		if (!_paintEnable) {
			return
		}
		event.preventDefault()

		var touch = event.touches[0]
		var x = touch.pageX-_canX+_ptOffset
		var y = touch.pageY-_canY+_ptOffset
		onTouchMove(x, y)
	}
	_sketch[0].ontouchend = function(event){
		if (!_paintEnable) {
			return
		}
		onTouchEnd()
	}

	_sketch[0].onmousedown = function(event){
		if (!_paintEnable) {
			return
		}
		event.preventDefault()

		var x = event.pageX-_canX+_ptOffset
		var y = event.pageY-_canY+_ptOffset
		if (!isTouchDevice()) {
			onTouchStart(x, y)
		}
	}

	_sketch[0].onmousemove = function(event){
		if (!_paintEnable) {
			return
		}
		event.preventDefault()

		var x = event.pageX-_canX+_ptOffset
		var y = event.pageY-_canY+_ptOffset
		if (!isTouchDevice()) {
			onTouchMove(x, y)
		}

		// console.log(event.offsetX, event.offsetX)
	}
	_sketch[0].onmouseup = function(event){
		if (!_paintEnable) {
			return
		}
		if (!isTouchDevice()) {
			onTouchEnd()
		}
	}

	//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
	function onTouchStart(x, y) {
		if (!_paintEnable) {
			return
		}

		if (_toolShow) {
			closeAllTool()
			return
		}

		//
		y -= _offsetY
		_touching = true

		_ctx.lineWidth = _currLineWidth
		_ctx.strokeStyle = _currColor

		_ctx.beginPath()
		_ctx.moveTo(x, y)
		_ctx.lineTo(x, y+0.01)
		_ctx.stroke()

		_currStroke.push(_currColor, _currLineWidth, x, y)

		//
		_brushTip.css({left:x+"px", top:y+"px"})
		_brushTip.show()

		//
		pushToSenderTouchStart(_currColor, _currLineWidth, x, y)

		//
		_lastX = x
		_lastY = y
	}

	function onTouchMove(x, y) {
		if (!_paintEnable) {
			return
		}

		if (!_touching) {
			return
		}
		y -= _offsetY

		var dx = x - _lastX
		var dy = y - _lastY
		if (dx*dx+dy*dy<4) {
			return
		}

		_ctx.beginPath()
		_ctx.moveTo(_lastX, _lastY)
		_ctx.lineTo(x, y)
		_ctx.stroke()
		

		_currStroke.push(x, y)

		//
		_brushTip.css({left:x+"px", top:y+"px"})

		//
		pushToSenderMove(x, y)

		//
		_lastX = x
		_lastY = y
	}

	function onTouchEnd() {
		if (!_paintEnable) {
			return
		}

		_touching = false
		var len = _currStroke.length
		if (len == 0) {
			return
		}

		if (len == 4) {
			_currStroke.push(_currStroke[2], _currStroke[3]+0.1)
		}

		// _replay.push(compressStroke(_currStroke))

		_undoStrokes.push(_currStroke)
		_undoLabel.css("color", _toolLabelColor)
		_redoLabel.css("color", _toolLabelDisableColor)
		if (_undoStrokes.length > _undoLimit) {
			var stroke = _undoStrokes.shift()
			drawStrokeData(_backCtx, stroke)

			//redraw tmp canvas
			_ctx.clearRect(0, 0, _can[0].width, _can[0].height)
			$(_undoStrokes).each(function(i, stroke) {
				drawStrokeData(_ctx, stroke)
			})
		}
		_currStroke = []
		_redoStrokes = []

		_brushTip.hide()

		pushToSenderTouchEnd()
	}

	function clearCanvas() {
		var w = _can[0].width
		var h = _can[0].height
		_ctx.clearRect(0, 0, w, h)
		_backCtx.clearRect(0, 0, w, h)
		_backCtx.fillStyle="#ffffff";
		_backCtx.fillRect(0,0,w,h);
		_currStroke = []
		_undoStrokes = []
		_redoStrokes = []
		// _replay = []
		_touching = false
		_brushTip.hide()

		_undoLabel.css("color", _toolLabelDisableColor)
		_redoLabel.css("color", _toolLabelDisableColor)
	}

	$("#clear").click(function() {
		// console.log(JSON.stringify(_replay))
		if (_toolShow) {
			return
		}

		if (confirm("确定清空画布吗？")) {
			clearCanvas()
			_undoLabel.css("color", _toolLabelDisableColor)
			_redoLabel.css("color", _toolLabelDisableColor)

			// //test
			// var replay = _replay
			// setTimeout(function() {
			// 	$(replay).each(function(i, stroke) {
			// 		stroke = decompressStroke(stroke)
			// 		drawStrokeData(_backCtx, stroke)
			// 	})
			// }, 1000)

			pushToSenderClear()
		}
	})

	//=============================
	var _palette = $("#palette")
	var _colorSample = $("#colorSample")
	var _tplPaletteItem = $("#template>.paletteItem")

	var _defaultPalette = {
		defaultColorIndex:7,
		colors:[
			"#ffffff","#000000","#9b9b9b","#ff4c62","#fec410",
			"#fdf902","#91c601","#516dfe","#2ccff5","#9c7cff",
			// "#af743f","#cca86d","#f0d881","#ffc4d6","#ff00b2",
			"#00A64C","#cca86d","#f0d881","#ffc4d6","#ff00b2",
		]
	}

	var defaultColorIndices = [1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14]
	_defaultPalette.defaultColorIndex = defaultColorIndices[Math.floor(Math.random()*defaultColorIndices.length)]
	
	function loadPalette(palette) {
		_palette.empty()
		var defaultColorIndex = palette.defaultColorIndex
		var colors = palette.colors
		$(colors).each(function(i, color) {
			var itemClone = _tplPaletteItem.clone()
			var icon = itemClone.find(".paletteItemIcon")
			icon.css("background-color", color)
			icon.attr("color", color)
			if (color[1] == "f" && color[3] == "f" &&color[5] == "f" ) {
				icon.css("border", "1px solid #ccc")
			}
			_palette.append(itemClone)
		})

		_palette.find(".paletteItem").click(function() {
			_palette.hide()
			_toolShow = false
			// var color = $(this).find(".paletteItemIcon").css("background-color")
			var color = $(this).find(".paletteItemIcon").attr("color")
			_colorSample.css("background-color", color)
			_ctx.strokeStyle = color
			_currColor = color
		})

		_colorSample.css("background-color", colors[defaultColorIndex])
		_ctx.strokeStyle = colors[defaultColorIndex]
		_currColor = _ctx.strokeStyle
	}
	loadPalette(_defaultPalette)

	$("#colorPicker").click(function() {
		if (_palette.css("display") == "none") {
			closeAllTool()
			_palette.show()
			_toolShow = true
		} else {
			_palette.hide()
			_toolShow = false
		}
	})

	//================================
	var _brushSizeBar = $("#brushSizeBar")
	$("#brushSize").click(function() {
		if (_brushSizeBar.css("display") == "none") {
			closeAllTool()
			_brushSizeBar.show()
			_toolShow = true
		} else {
			_brushSizeBar.hide()
			_toolShow = false
		}
	})

	function setBrushSize(size) {
		size = parseInt(size)
		_currLineWidth = size
		_ctx.lineWidth = size
		var sizePx = size+"px"
		$("#brushSample").css({width:sizePx, height:sizePx, "margin-top":-(size/2)+"px"})

		_brushTip.css({width:sizePx, height:sizePx, "margin-left":-(size/2)+"px", "margin-top":-(size/2)+"px"})
	}
	$(".brushSizeItem").click(function() {
		var size = $(this).find(".brushSizeLabel").text()
		setBrushSize(size)
		_brushSizeBar.hide()
		_toolShow = false
	})

	setBrushSize(4)

	function closeAllTool() {
		_toolShow = false
		_palette.hide()
		_brushSizeBar.hide()
	}

	function drawStrokeData(ctx, stroke) {
		var color = stroke[0]
		var size = stroke[1]
		var ptX = stroke[2]
		var ptY = stroke[3]

		ctx.lineWidth = size
		ctx.strokeStyle = color

		ctx.beginPath()
		ctx.moveTo(ptX, ptY)

		var ptNum = (stroke.length - 4)/2
		for (var i = 0; i < ptNum; i++) {
			ptX = stroke[4+i*2]
			ptY = stroke[4+i*2+1]
			ctx.lineTo(ptX, ptY)
		}
		ctx.stroke()
	}

	$("#undo").click(function() {
		if (_toolShow) {
			return
		}
		undo()
		pushToSenderUndo()
		_redoLabel.css("color", _toolLabelColor)
		if (_undoStrokes.length == 0) {
			_undoLabel.css("color", _toolLabelDisableColor)
		}
	})

	function undo() {
		if (_undoStrokes.length == 0) {
			return
		}
		var stroke = _undoStrokes.pop()
		_redoStrokes.push(stroke)

		redrawUndoCanvas()

		// _replay.pop()
	}

	$("#redo").click(function() {
		if (_toolShow) {
			return
		}
		redo()

		if (_redoStrokes.length == 0) {
			_redoLabel.css("color", _toolLabelDisableColor)
		}
		_undoLabel.css("color", _toolLabelColor)
		pushToSenderRedo()
	})

	function redo() {
		if (_redoStrokes.length == 0) {
			return
		}
		
		var stroke = _redoStrokes.pop()
		_undoStrokes.push(stroke)

		redrawUndoCanvas()

		// _replay.push(compressStroke(stroke))
	}

	function redrawUndoCanvas() {
		_ctx.clearRect(0, 0, _can[0].width, _can[0].height)
		$(_undoStrokes).each(function(i, stroke) {
			drawStrokeData(_ctx, stroke)
		})
	}

	// function compressStroke(stroke) {
	// 	var color = stroke[0]
	// 	var size = stroke[1]
	// 	var ptX = stroke[2]
	// 	var ptY = stroke[3]

	// 	out = [color, size, ptX, ptY]

	// 	var ptNum = (stroke.length - 4)/2
	// 	for (var i = 0; i < ptNum; i++) {
	// 		var x = stroke[4+i*2]
	// 		var y = stroke[4+i*2+1]
	// 		out.push(x-ptX, y-ptY)
	// 		ptX = x
	// 		ptY = y
	// 	}
	// 	return out
	// }
	// function decompressStroke(stroke) {
	// 	var color = stroke[0]
	// 	var size = stroke[1]
	// 	var ptX = stroke[2]
	// 	var ptY = stroke[3]

	// 	out = [color, size, ptX, ptY]

	// 	var ptNum = (stroke.length - 4)/2
	// 	for (var i = 0; i < ptNum; i++) {
	// 		var x = stroke[4+i*2]
	// 		var y = stroke[4+i*2+1]
	// 		x += ptX
	// 		y += ptY
	// 		out.push(x, y)
	// 		ptX = x
	// 		ptY = y
	// 	}
	// 	return out
	// }

	//=========================================
	var _sendData = []
	function pushToSenderTouchStart(color, lineWidth, x, y) {
		_sendData.push("start", color, lineWidth, x, y)
	}

	function pushToSenderMove(x, y) {
		_sendData.push(x-_lastX, y-_lastY)
	}

	function pushToSenderTouchEnd() {
		_sendData.push("end")
	}

	function pushToSenderUndo() {
		_sendData.push("undo")
	}

	function pushToSenderRedo() {
		_sendData.push("redo")
	}

	function pushToSenderClear() {
		_sendData.push("clear")
	}

	$("#testBtn1").click(function(){
		// enablePaint(!_paintEnable) 

		// showUserCover(0, true, "+22")
		// showPencil(0)
		// setTimer(5)
		// fadeIn(_endRoundPanel, 200)

		// throwRose()
	})

	function saveUserWork(userInfo, word, tip, roundIndex, replayId) {
		var w = _userWorkCan[0].width
		var h = _userWorkCan[0].height
		_userWorkCtx.fillStyle="#ffffff"
		_userWorkCtx.fillRect(0,0,w,h)

		$(_undoStrokes).each(function(i, stroke) {
			drawStrokeData(_backCtx, stroke)
		})

		var imgData=_backCtx.getImageData(0,0,_backCan[0].width,_backCan[0].height)

		_userWorkCtx.putImageData(imgData,0,0)

		//text
		_userWorkCtx.fillStyle="#FF5A81"
		_userWorkCtx.font="18px arial"
		// _userWorkCtx.fillText(userName+"画的"+word+"（"+tip+"）",10,20)
		_userWorkCtx.fillText(userInfo.NickName+"作品"+"（"+word.length+"个字，"+tip+"）",10,20)
		// _userWorkCtx.font="14px arial"
		// _userWorkCtx.fillText('玩《你画我猜》请关注微信公众号：二店长的小游戏',10,356)
		// _userWorkCtx.fillText('或登录：erdianzhang.com',10,372)

		var img = _userWorkCan[0].toDataURL("image/png")
		// //
		// var ctx = _userWorkCtx
		// // ctx.drawImage(can,0,0,can1.width, can1.height)
		// ctx.textAlign = "right"
		// ctx.textBaseline = "top"
		// ctx.font="16px Arial"
		// ctx.fillStyle = "rgba(255,255,255,1)"
		// ctx.shadowColor = "#000"
		// ctx.shadowOffsetX = 1;
		// ctx.shadowOffsetY = 1;
		// ctx.shadowBlur = 1;
		// ctx.fillText("",w-5,5);

		// imgData = can1.toDataURL("image/jpeg", 0.8)

		//
		var elem = $('<div class="userWork"><div class="userWorkHeader"></div><img src='+img+'><button type="button" class="shareBtn btn btn-primary">发给朋友猜</button></div>')
		var button = elem.find(".shareBtn")
		var header = elem.find(".userWorkHeader")
		header.text("答案："+word)
		// button[0].index = roundIndex
		button.click(function(){
			var url = addVer("replay.html?index="+roundIndex+"&share=1&key="+_key)
			location.replace(url)
		})
		$("#userWorks").append(elem)
		button.hide()

		//save
		var key = _key+"/"+roundIndex
		lscache.set("userWorkImg/"+key, img, 3000)
		var userWorkInfo = {
			userName: userInfo.NickName,
			avatar:userInfo.AvatarKey,
			word: word,
			tip: tip,
			replayId: replayId,
		}
		// lscache.set("userWorkInfo/"+key, userWorkInfo, 3000)


	}

	$("#testBtn2").click(function(){
		// throwShoe()
		// var msg = {
		// 	Type:"throwShoe",
		// }
		// wsSend(_conn, msg)
		fadeOut(_endGameLayer, 200)
	})

	function throwRose() {
		var rose = $('<div id="rose"></div>')
		_sketch.append(rose)
		rose.css({
			left:-rose.width()/2+"px",
			top:-rose.height()/2+"px",
		})

		// var x0 = "100px"
		var w = 360
		var x0 = Math.floor(((360-100)*Math.random()+50))
		var y0 = 20+Math.random()*50
		var scale0 = 0.5
		var rot0 = -30+Math.floor(Math.random()*60)+"deg"
		var x1 = x0-100+200*Math.random()
		if (x1 < 50) {
			x1 = 50
		} else if (x1 > w-50) {
			x1 = w-50
		}
		var y1 = 1000
		var scale1 = 0.2

		var x0px = x0+"px"
		var y0px = y0+"px"
		var x1px = x1+"px"
		var y1px = y1+"px"

		rose.css("-webkit-transform","translate("+x0px+", "+y0px+") scale("+scale0+") rotate("+rot0+")")
		
		rose.velocity("stop")
		rose.velocity({
			translateX:x0px,
			translateY:y0px,
			rotateZ:rot0,
			scale:scale0,
		}, {
			duration:0,
		})
		rose.velocity({
			translateY:y1px,
			// rotateZ:"30deg",
		}, {
			easing:"easeInCubic",
			duration:1600,
			complete: function(elem) { 
				$(elem).remove()
			}
		})
		rose.velocity({
			translateX:x1px,
			scale:scale1,
		}, {
			easing:"easeOutQuart",
			duration:1600,
			queue:false,
		})

		rose.velocity({
			"opacity":0,
		},{
			delay:1000,
			duration:300,
			queue:false,
		})
	}

	function throwShoe() {
		var shoe = $('<div id="shoe"></div>')
		var mud = $('<div id="mud"></div>')
		_sketch.append(shoe)
		_sketch.append(mud)
		shoe.css({
			left:-shoe.width()/2+"px",
			top:-shoe.height()/2+"px",
		})
		mud.css({
			left:-shoe.width()/2+"px",
			top:-shoe.height()/2+"px",
		})

		var w = 360
		var x0 = (360-100)*Math.random()+50
		var y0 = 180+Math.random()*50
		var rot0 = (750+Math.random()*100)
		if (Math.random()<0.5){
			rot0 = -rot0
		}
		rot0 += "deg"
		var rot1 = (-60+120*Math.random())+"deg"
		var x1 = x0-100+200*Math.random()
		if (x1 < 50) {
			x1 = 50
		} else if (x1 > w-50) {
			x1 = w-50
		}
		var y1 = 40+Math.random()*100

		var x0px = x0+"px"
		var y0px = y0+"px"
		var x1px = x1+"px"
		var y1px = y1+"px"


		shoe.css("-webkit-transform",'translate('+x0px+', '+y0px+') scale(0.5) rotate('+rot0+')')
		// mud.css("-webkit-transform",'translate('+x1px+', '+y1px+') scale(0.4) rotate('+rot1+')')
		// mud.css("transform",'translate('+x1px+', '+y1px+') scale(0.4) rotate('+rot1+')')
		mud.css("opacity",0)

		shoe.velocity({
			translateX:x0px,
			translateY:y0px,
			rotateZ:rot0,
			scale:0.5,
		}, {
			duration:0,
		})
		mud.velocity({
			translateX:x1px,
			translateY:y1px,
			rotateZ:rot1,
			scale:0.4,
		}, {
			duration:1.01,
		})
		shoe.velocity({
			translateY:y1px,
			rotateZ:[rot1, "linear"],
		}, {
			easing:"easeOutCubic",
			duration:600,
		})

		shoe.velocity({
			translateX:x1px,
			scale:0.4,
		}, {
			easing:"easeInQuad",
			duration:600,
			queue:false,
		})

		shoe.velocity({
			translateY:"1000px",
			// rotateZ:"30deg",
		}, {
			delay:500,
			easing:"easeInCubic",
			duration:1600,
			complete: function(elem) { 
				$(elem).remove()
			}
		})

		shoe.velocity(
			{"opacity":0}, {
			delay:1600,
			easing:"easeInQuad",
			duration:600,
			queue:false,
		})

		mud.velocity({
			"opacity":1,
			scale:0.4,
		},{
			delay:600,
			duration:0,
		})

		mud.velocity({
			"opacity":0,
		},{
			delay:2000,
			duration:500,
		})
	}

	wsBind("throwRose", function(msg) {
		throwRose()
	})
	wsBind("throwShoe", function(msg) {
		throwShoe()
	})

	function sendStroke() {
		if (_sendData.length == 0) {
			return
		}
		var msg = {
			Type:"draw",
			Data:_sendData,
		}
		wsSend(_conn, msg)
		_sendData = []
	}

	var _recvData = []
	var _recvLastX
	var _recvLastY
	var _drawWaitMsec = 10
	var _currReadIndex = 0

	function onRecv(data) {
		_recvData = _recvData.concat(data)
		_drawWaitMsec = 1000/(_recvData.length-_currReadIndex)*2
	}

	function recvDrawOne() {
		var ctx = _ctx
		if (_recvData.length == 0 || _currReadIndex >= _recvData.length) {
			setTimeout(recvDrawOne, 100)
			return
		}
		var ptr = _recvData[_currReadIndex]

		if (ptr == "start") {
			var i = _currReadIndex
			
			var color = _recvData[i+1]
			var lineWidth = _recvData[i+2]
			ctx.strokeStyle = color
			ctx.lineWidth = lineWidth
			var x = _recvData[i+3]
			var y = _recvData[i+4]
			ctx.beginPath()
			ctx.moveTo(x, y)
			ctx.lineTo(x, y+0.01)
			ctx.stroke()
			_recvLastX = x
			_recvLastY = y
			_currReadIndex += 5
			_currStroke.push(color, lineWidth, x, y)
		} else if (ptr == "end") {
			_currReadIndex+=1

			var len = _currStroke.length
			if (len == 0) {
				setTimeout(recvDrawOne, 100)
				return
			}

			if (len == 4) {
				_currStroke.push(_currStroke[2], _currStroke[3]+0.1)
			}

			// _replay.push(compressStroke(_currStroke))

			_undoStrokes.push(_currStroke)
			if (_undoStrokes.length > _undoLimit) {
				var stroke = _undoStrokes.shift()
				drawStrokeData(_backCtx, stroke)

				//redraw tmp canvas
				_ctx.clearRect(0, 0, _can[0].width, _can[0].height)
				$(_undoStrokes).each(function(i, stroke) {
					drawStrokeData(_ctx, stroke)
				})
			}
			_currStroke = []
			_redoStrokes = []

		} else if (ptr == "undo") {
			_currReadIndex+=1
			undo()
		} else if (ptr == "redo") {
			_currReadIndex+=1
			redo()
		} else if (ptr == "clear") {
			_currReadIndex+=1
			clearCanvas()
		}else {
			var i = _currReadIndex
			var x = _recvData[i]
			var y = _recvData[i+1]
			x += _recvLastX
			y += _recvLastY

			ctx.moveTo(_recvLastX, _recvLastY)
			ctx.lineTo(x, y)
			ctx.stroke()
			_recvLastX = x
			_recvLastY = y
			_currReadIndex += 2
			_currStroke.push(x, y)
		}

		setTimeout(recvDrawOne, _drawWaitMsec)
	}

	var _sendTimer = setInterval(sendStroke, 500)
	// var _recvDrawTimer = setInterval(recvDrawOne, 10)

	function drawReplay() {
		var strokes = []
		while (true) {
			var ctx = _ctx
			if (_recvData.length == 0 || _currReadIndex >= _recvData.length) {
				break
			}
			var ptr = _recvData[_currReadIndex]

			if (ptr == "start") {
				var i = _currReadIndex
				
				var color = _recvData[i+1]
				var lineWidth = _recvData[i+2]
				ctx.strokeStyle = color
				ctx.lineWidth = lineWidth
				var x = _recvData[i+3]
				var y = _recvData[i+4]
				// ctx.beginPath()
				// ctx.moveTo(x, y)
				// ctx.lineTo(x, y+0.01)
				// ctx.stroke()
				_recvLastX = x
				_recvLastY = y
				_currReadIndex += 5
				_currStroke.push(color, lineWidth, x, y)
			} else if (ptr == "end") {
				_currReadIndex+=1

				var len = _currStroke.length
				if (len == 0) {
					break
				}
				if (len == 4) {
					_currStroke.push(_currStroke[2], _currStroke[3]+0.1)
				}

				strokes.push(_currStroke)

				// _undoStrokes.push(_currStroke)
				// if (_undoStrokes.length > _undoLimit) {
				// 	var stroke = _undoStrokes.shift()
				// 	drawStrokeData(_backCtx, stroke)

				// 	//redraw tmp canvas
				// 	_ctx.clearRect(0, 0, _can[0].width, _can[0].height)
				// 	$(_undoStrokes).each(function(i, stroke) {
				// 		drawStrokeData(_ctx, stroke)
				// 	})
				// }

				_currStroke = []
				_redoStrokes = []

			} else if (ptr == "undo") {
				_currReadIndex+=1
				var stroke = strokes.pop()
				_redoStrokes.push(stroke)
			} else if (ptr == "redo") {
				_currReadIndex+=1
				var stroke = _redoStrokes.pop()
				strokes.push(stroke)
			} else if (ptr == "clear") {
				_currReadIndex+=1
				strokes = []
				_currStroke = []
				_undoStrokes = []
				_redoStrokes = []
			}else {
				var i = _currReadIndex
				var x = _recvData[i]
				var y = _recvData[i+1]
				x += _recvLastX
				y += _recvLastY

				// ctx.moveTo(_recvLastX, _recvLastY)
				// ctx.lineTo(x, y)
				// ctx.stroke()
				_recvLastX = x
				_recvLastY = y
				_currReadIndex += 2
				_currStroke.push(x, y)
			}
		}

		var strokeNum = strokes.length
		$(strokes).each(function(i, stroke) {
			if (i < strokeNum - _undoLimit) {
				drawStrokeData(_backCtx, stroke)
			} else {
				_undoStrokes.push(stroke)
				drawStrokeData(_ctx, stroke)
			}
		})

		//draw currStroke
		var stroke = _currStroke
		if (stroke.length >= 4) {
			var color = stroke[0]
			var size = stroke[1]
			var ptX = stroke[2]
			var ptY = stroke[3]

			ctx.lineWidth = size
			ctx.strokeStyle = color

			ctx.beginPath()
			ctx.moveTo(ptX, ptY)
			// ctx.lineTo(ptX, ptY+0.1)

			var ptNum = (stroke.length - 4)/2
			for (var i = 0; i < ptNum; i++) {
				ptX = stroke[4+i*2]
				ptY = stroke[4+i*2+1]
				ctx.lineTo(ptX, ptY)
			}
			ctx.stroke()
		}
		
	}

	//draw replay
	// function drawReplay() {
	// 	var ctx = _ctx
	// 	var readIndex = 0
	// 	var replay = _gameData.Replay
	// 	var recvLastX = 0
	// 	var recvLastY = 0
	// 	var currStroke = []
	// 	var undoStrokes = []
	// 	var redoStrokes = []

	// 	while (true) {
	// 		var ctx = _ctx
	// 		if (!replay || replay.length == 0 || readIndex >= replay.length) {
	// 			return
	// 		}
	// 		var ptr = replay[readIndex]

	// 		if (ptr == "start") {
	// 			var i = readIndex
				
	// 			var color = replay[i+1]
	// 			var lineWidth = replay[i+2]
	// 			ctx.strokeStyle = color
	// 			ctx.lineWidth = lineWidth
	// 			var x = replay[i+3]
	// 			var y = replay[i+4]
	// 			ctx.beginPath()
	// 			ctx.moveTo(x, y)
	// 			ctx.lineTo(x, y+0.01)
	// 			ctx.stroke()
	// 			recvLastX = x
	// 			recvLastY = y
	// 			readIndex += 5
	// 			currStroke.push(color, lineWidth, x, y)
	// 		} else if (ptr == "end") {
	// 			readIndex+=1

	// 			var len = currStroke.length
	// 			if (len == 0) {
	// 				return
	// 			}

	// 			if (len == 4) {
	// 				currStroke.push(currStroke[2], currStroke[3]+0.1)
	// 			}

	// 			// _replay.push(compressStroke(_currStroke))

	// 			undoStrokes.push(currStroke)
	// 			if (undoStrokes.length > _undoLimit) {
	// 				var stroke = undoStrokes.shift()
	// 				drawStrokeData(_backCtx, stroke)

	// 				//redraw tmp canvas
	// 				ctx.clearRect(0, 0, _can[0].width, _can[0].height)
	// 				$(undoStrokes).each(function(i, stroke) {
	// 					drawStrokeData(ctx, stroke)
	// 				})
	// 			}
	// 			currStroke = []
	// 			redoStrokes = []

	// 		} else if (ptr == "undo") {
	// 			readIndex+=1
	// 			undo()
	// 		} else if (ptr == "redo") {
	// 			readIndex+=1
	// 			redo()
	// 		} else if (ptr == "clear") {
	// 			readIndex+=1
	// 			clearCanvas()
	// 		}else {
	// 			var i = readIndex
	// 			var x = replay[i]
	// 			var y = replay[i+1]
	// 			x += recvLastX
	// 			y += recvLastY

	// 			ctx.moveTo(recvLastX, recvLastY)
	// 			ctx.lineTo(x, y)
	// 			ctx.stroke()
	// 			recvLastX = x
	// 			recvLastY = y
	// 			readIndex += 2
	// 			currStroke.push(x, y)
	// 		}
	// 	}
	// }


	//check key
	var key = getUrlParam("key")
	if (!key) {
		alert("参数错误")
		return
	}
	msg = {
		Key:key,
	}
	post("draw/checkKey", msg, function(resp) {
		console.log(resp)
	}, function(resp){
		window.history.go(-1)
	})
	_key = key

	//web socket
	var wsUrl = "ws://"+HOST+"/ws/draw?key="+key
	if (getUrlParam("happiness")) {
		wsUrl += "&happiness=1"
	}
	var _conn = new WebSocket(wsUrl)
	_conn.onclose = function(evt) {
		console.log("ws close")
		gotoWsErrorPage()
	}
	_conn.onerror = function(evt) {
		console.log("ws error")
		gotoWsErrorPage()
	}
	_conn.onmessage = function(evt) {
		var msg = JSON.parse(""+evt.data)
		if (msg.Type in _wsProcMap) {
			_wsProcMap[msg.Type](msg)
		} else {
			console.log(msg)
		}
	}

	//wsbind
	wsBind("err", function(msg) {
		console.log(msg)
	})

	var _gameData = null
	var _myUserInfo = null
	var _mySeatIndex = -1
	var _userBar = $("#userBar")
	var _tplUserFrame = $("#template>.userFrame")
	var _tipLabel = $("#tipLabel")
	var _timerLabel = $("#timerLabel")

	function getSeatIndex(userId) {
		var seatIndex = -1
		$(_gameData.Seats.Seats).each(function(i, seat) {
			if (seat.UserInfo.Id == userId) {
				seatIndex = i
				return false
			}
		})
		return seatIndex
	}

	wsBind("gameData", function(msg) {
		console.log(msg)
		_gameData = msg.GameData
		_myUserInfo = msg.MyUserInfo
		_mySeatIndex = getSeatIndex(_myUserInfo.Id)

		if (_gameData.State == DRAWST_END) {
			alert("游戏已结束")
			window.history.go(-1)
		}

		if (!_gameData.RoomKey) {
			$("#leaveBtn").text("返回")
		}

		_userBar.empty()
		$(_gameData.Seats.Seats).each(function(i, seat) {
			var frameClone = _tplUserFrame.clone()
			frameClone.find(".userName").text(seat.UserInfo.NickName)
			frameClone.find(".avatarImg").attr("src", makeAvatarUrl(seat.UserInfo.AvatarKey, 40))
			_userBar.append(frameClone)

			if (seat.Conn == null) {
				showOffline(i, true)
			}
		})

		if (_gameData.Replay) {
			$(_gameData.Replay).each(function(i, d){
				_recvData = _recvData.concat(d.Draw)
			})
			drawReplay()
		}
		recvDrawOne()

		//tip pencil 
		if (_gameData.State == DRAWST_ENTER) {
			setTip("等待成员进入中")

		} else if (_gameData.State == DRAWST_ROUND) {
			var tip = _gameData.Tip
			setTip("提示："+tip[0]+"，"+tip[1])

			var drawerIndex = _gameData.RoundIndex % _gameData.Seats.Seats.length
			showPencil(drawerIndex)
			enablePaint(_mySeatIndex == drawerIndex)
		} else if (_gameData.State == DRAWST_END) {
			setTip("游戏结束")
			enablePaint(false)
		}

		//timer
		var timerSec = msg.TimerSec
		setTimer(timerSec)

		//score
		$(_gameData.Players).each(function(i, player){
			setUserScore(i, player.Score, player.RoundScore)
		})
	})
	function showPencil(index) {
		fadeOut(_userBar.find(".pencil"), 500)
		fadeIn(_userBar.find(".userFrame:nth-child("+(index+1)+") .pencil"))
	}

	function showOffline(index, show) {
		var div = $($(".offline")[index])
		if (show) {
			fadeIn(div, 200)
		} else {
			fadeOut(div, 200)
		}
	}

	// function showUserCover(index, show, text, duration) {
	// 	var elem = getUserCover(index)
	// 	if (duration == null) {
	// 		duration = 200
	// 	}
	// 	if (show) {
	// 		fadeIn(elem, duration)
	// 	} else {
	// 		fadeOut(elem, duration)
	// 	}
	// 	elem.text(text)
	// }

	function setUserScore(index, score, roundScore) {
		// console.log(index, score, roundScore)
		_gameData.Players[index].RoundScore = roundScore
		_gameData.Players[index].Score = score
		
		var div = $(".userFrame:nth-child("+(index+1)+") .userScore")
		if (roundScore==0) {
			div.text(score)
		} else {
			div.text(score+"（+"+roundScore+"）")
		}
	}

	function setTip(text) {
		_tipLabel.text(text)
	}

	_outputLabel = $("#outputLabel")
	_outputTimer = null
	function setOutputLabel(text, showMsec) {
		_outputLabel.text(text)
		fadeIn(_outputLabel, 500)
		clearTimeout(_outputTimer)
		_outputTimer = setTimeout(function(){fadeOut(_outputLabel, 500)}, showMsec)
	}

	wsBind("enter", function(msg) {
		console.log(msg)
		var userInfo = msg.UserInfo
		var seatIndex = getSeatIndex(userInfo.Id)
		var player = _gameData.Players[seatIndex]
		showOffline(seatIndex, false)
		// if (_gameData.State == DRAWST_ROUND) {
		// 	var roundScore = _gameData.Players[seatIndex].RoundScore
		// 	if (roundScore > 0) {
		// 		showUserCover(seatIndex, true, "+"+roundScore)
		// 	} else {
		// 		showUserCover(seatIndex, false, "")
		// 	}
		// } else {
		// 	showUserCover(seatIndex, false, "")
		// }
	})

	wsBind("quit", function(msg) {
		console.log(msg)
		var userInfo = msg.UserInfo
		var seatIndex = getSeatIndex(userInfo.Id)
		showOffline(seatIndex, true)
		_gameData.Seats.Seats[seatIndex].Conn = null
	})

	wsBind("quitGame", function(msg) {
		alert("朋友们都离开了")
		window.history.go(-1)
	})

	wsBind("errPlayerNum", function(msg) {
		var notInPlayers = msg.NotInPlayers
		alert("您的朋友"+notInPlayers.join(",")+"可能因网络问题没进来，请重新组队进入")
		// window.history.go(-1)
	})

	wsBind("errNotEnoughPlayer", function(msg) {
		alert("人数不够，有朋友可能因网络问题没进来，请重新组队进入")
		// window.history.go(-1)
	})

	wsBind("startGame", function(msg) {
		console.log(msg)
		setTip("游戏开始")
		setOutputLabel("游戏开始", 2000)
		// fadeOut(_endRoundPanel, 200)
		fadeOut(_endGameLayer, 200)
	})

	wsBind("draw", function(msg) {
		var data = msg.Data
		onRecv(data)
	})

	wsBind("startRound", function(msg) {
		var roundIndex = msg.RoundIndex
		var tip = msg.Tip
		var roundSec = msg.RoundSec
		var drawerIndex = msg.DrawerIndex

		_gameData.RoundIndex = roundIndex
		_gameData.Tip = tip
		_gameData.State = DRAWST_ROUND

		showPencil(drawerIndex)
		setTimer(roundSec)
		// hideAllUserCover()
		//set scores
		$(_gameData.Players).each(function(i, player){
			_gameData.Players[i].RoundScore = 0
			setUserScore(i, player.Score, 0)
		})

		if (_mySeatIndex == drawerIndex) {
			enablePaint(true)
			$("#scene").velocity(
				"scroll", {
				duration: 400,
			})
		} else {
			enablePaint(false)
			setTip("提示："+tip[0])
			// setTip("提示："+tip[0]+"("+(roundIndex+1)+"/"+_gameData.RoundNum+")")
			var roundIndex = _gameData.RoundIndex
			setTimeout(function(){
				if (_gameData.State == DRAWST_ROUND && roundIndex == _gameData.RoundIndex) {
					setTip("提示："+tip[0]+"，"+tip[1])
					pushTalk("新提示："+tip[1], _sysTextColor)
				}
			}, 20000)

			var drawerInfo = _gameData.Seats.Seats[drawerIndex].UserInfo
			setOutputLabel("第"+(roundIndex+1)+"/"+_gameData.RoundNum+"轮："+drawerInfo.NickName+"画，我猜", 3000)
		}

		_recvData = []
		_currReadIndex = 0

		clearCanvas()
		_brushTip.hide()

		fadeOut(_endRoundPanel, 200)
	})
	wsBind("what", function(msg) {
		console.log(msg)
		var word = msg.Word
		setTip("我画："+word+"（"+msg.Tip[1]+"）")
		setOutputLabel("第"+(msg.RoundIndex+1)+"/"+_gameData.RoundNum+"轮："+'我画 "'+word+'"', 3000)
	})

	wsBind("endRound", function(msg) {
		console.log(msg)
		_gameData.State = DRAWST_ROUND_END
		setTimer(msg.Sec)
		enablePaint(false)
		setTip("回合结束")

		var drawerIndex = _gameData.RoundIndex % _gameData.Seats.Seats.length
		if (_mySeatIndex == drawerIndex) {
			setOutputLabel("回合结束", 5000)
		} else {
			_endRoundText.text("答案："+msg.Word)
			fadeIn(_endRoundPanel, 200)
		}

		var userInfo = _gameData.Seats.Seats[drawerIndex].UserInfo
		saveUserWork(userInfo, msg.Word, _gameData.Tip[1], _gameData.RoundIndex, msg.ReplayId)
	})

	$("#flowerBtn").click(function(){
		fadeOut(_endRoundPanel, 200)
		throwRose()

		var msg = {
			Type:"throwRose",
		}
		wsSend(_conn, msg)
	})

	$("#shoeBtn").click(function(){
		fadeOut(_endRoundPanel, 200)
		throwShoe()

		var msg = {
			Type:"throwShoe",
		}
		wsSend(_conn, msg)
	})

	wsBind("endGame", function(msg) {
		console.log(msg)
		_gameData.State = DRAWST_END
		fadeOut(_userBar.find(".pencil"), 500)
		enablePaint(false)
		setTip("游戏结束")

		var sec = msg.RestartSec
		// setTimer(sec)

		// setTimeout(function(){
		// 	window.history.go(-1)
		// }, sec*1000)

		//end panel
		var players = msg.Players
		var ranks = []
		$(_gameData.Seats.Seats).each(function(i, seat){
			ranks.push({
				userInfo:seat.UserInfo,
				score:players[i].Score,
			})
		})

		ranks = ranks.sort(function(a, b){
			return b.score-a.score
		})

		var delay = 5000
		if (_endRoundPanel._hidden && _outputLabel._hidden) {
			delay = 0
		}

		setTimeout(function(){
			fadeOut(_endRoundPanel, 200)
			fadeIn(_endGameLayer, 400)

			var rankRows = _endGamePanel.find(".rankRow")
			$(ranks).each(function(i, rank){
				var rankRow = $(rankRows[i])
				rankRow.css("visibility", "visible")
				rankRow.find(".rankNum").text(i+1)
				rankRow.find(".avatarImg").attr("src", makeAvatarUrl(rank.userInfo.AvatarKey, 30))
				rankRow.find(".rankName").text(rank.userInfo.NickName)
				rankRow.find(".rankScore").text(rank.score+"分")
			})
		}, delay)

		$("#userWorks").show()
		// var ranks = [{score:5}, {score:3}, {score:7}]
		// ranks = ranks.sort(function(a, b){
		// 	return b.score-a.score
		// })
		// console.log(ranks)

		$("#scene").css({"overflow":"auto"})
	})

	$("#leaveBtn").click(function(){
		window.history.go(-1)
	})
	$("#playAgainBtn").click(function(){
		fadeOut(_endGameLayer, 200)
	})
	
	$("#bbsBtn").click(function(){
		window.location.href = "http://club.erdianzhangtest.kuaizhan.com/forum/Vn14nt2HJh9iuHJn"
	})
	

	var _sysTextColor = "#FFD12B"

	wsBind("correct", function(msg) {
		console.log(msg)
		var talkerIndex = msg.TalkerIndex
		var talkerRoundScore = msg.TalkerRoundScore
		var talkerScore = msg.TalkerScore
		var painterIndex = msg.PainterIndex
		var painterRoundScore = msg.PainterRoundScore
		var painterScore = msg.PainterScore
		var changeTimerSec = msg.ChangeTimerSec

		var talkerUserInfo = _gameData.Seats.Seats[talkerIndex].UserInfo
		var painterUserInfo = _gameData.Seats.Seats[painterIndex].UserInfo

		setUserScore(talkerIndex, talkerScore, talkerRoundScore)
		setUserScore(painterIndex, painterScore, painterRoundScore)

		if (talkerUserInfo.Id == _myUserInfo.Id) {
			pushTalk("我 猜对了答案，+"+talkerRoundScore+"分", "#FDA873")
		} else {
			pushTalk(talkerUserInfo.NickName+" 猜对了答案，+"+talkerRoundScore+"分", _sysTextColor)
		}

		if (changeTimerSec > 0 && _gameData.Seats.Seats.length > 2) {
			setTimer(changeTimerSec)
			pushTalk("答题时间更改为"+changeTimerSec+"秒", _sysTextColor)
		}
	})

	//======================
	function enablePaint(enable) {
		_paintEnable = enable

		if (enable) {
			_toolBar.show()
			_talkBar.hide()
			_talkInput.val("")
			_talkInput.blur()
		} else {
			_toolBar.hide()
			_talkBar.show()
			_palette.hide()
			_brushSizeBar.hide()
		}
	}

	enablePaint(false)
	_toolBar.hide()
	_talkBar.hide()

	var _timerSec = -1
	var _timer = null
	function setTimer(sec) {
		if (_timer) {
			clearTimeout(_timer)
			_timer = null
		}
		if (sec == 0) {
			_timerLabel.text(0)
			return
		}
		_timerSec = sec
		timerRun()
	}

	function timerRun() {
		if (_timerSec < 0) {
			_timerLabel.text(0)
			return
		}
		_timerLabel.text(_timerSec)
		_timerSec -= 1
		_timer = setTimeout(timerRun, 1000)
	}

	//=======================
	var _talkLabelTpl = $("#template>.talkLabel")
	var _talkInput = $("#talkInput")
	var _talkCont = $("#talkCont")

	$("#talkBtn").click(function(){
		sendTalk()
	})

	_talkInput.bind('keyup', function(event){
        if (event.keyCode=="13"){
            sendTalk()
        }
    });

  function sendTalk() {
  	var t = _talkInput.val()
		if (t) {
			t = t.tran()
			_talkInput.val("")
			_talkInput.blur()
			var msg = {
				Type:"talk",
				Text:t,
			}
			wsSend(_conn, msg)
		}
  }

  wsBind("talk", function(msg) {
		var text = msg.Text
		var userName = msg.UserName

		text = userName+"："+text
		pushTalk(text)
	})

    var _talkTimer = null
    var _talkQueue = []
    var _flyingTalkNum = 0

	function pushTalk(text, color) {
		if (!color) {
			color = "#fff"
		}
		_talkQueue.push([text, color])
		if (!_talkTimer) {
			if (_flyingTalkNum == 0) {
				fadeIn(_talkCont, 500)
			}
			popTalk()
		}
	}

	function popTalk() {
		if (_talkQueue.length == 0) {
			clearTimeout(_talkTimer)
			_talkTimer = null
			return
		}
		_flyingTalkNum++

		var textNColor = _talkQueue.shift()
		var text = textNColor[0]
		var color = textNColor[1]

		var labelClone = _talkLabelTpl.clone()
		labelClone.text(text)
		labelClone.css("color", color)
		_talkCont.append(labelClone)
		var w = labelClone.width()

		labelClone.css("left", 360)
		labelClone.velocity({
			left:"-200px",
		}, {
			easing:"linear",
			duration:4000,
			complete: function(elem) { 
				$(elem).remove()
				_flyingTalkNum--
				if (_flyingTalkNum == 0) {
					fadeOut(_talkCont, 500)
				}
			}
		})

		//
		_talkTimer = setTimeout(popTalk, w*8+200)
	}

	if (isTouchDevice()) {
		var offsetY = "0px"
		if (isIos()) {
			offsetY = "387px"
		} else if (isAndroid()) {
			offsetY = "287px"
		}

		var _infoBar = $("#infoBar")
		_talkInput.focus(function() {
			_infoBar.velocity({
				top:offsetY,
			},{
				duration: 400,
				ease:"easeOutCubic",
			})
		})
		_talkInput.blur(function() {
			_infoBar.velocity({
				top:"0px",
			},{
				duration: 400,
				ease:"easeOutCubic",
			})
			// $("#scene").velocity(
			// 	"scroll", {
			// 	duration: 400,
			// })
		})
	}

	

	// initTaobaoAd()

})
